package com.uduemc.biso.node.web.api.controller;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.core.common.entities.PageSystem;
import com.uduemc.biso.node.core.entities.SPage;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.dto.RequestSPage;
import com.uduemc.biso.node.web.api.dto.RequestSPageCopy;
import com.uduemc.biso.node.web.api.dto.RequestSPageRewrite;
import com.uduemc.biso.node.web.api.exception.HostSetuptException;
import com.uduemc.biso.node.web.api.pojo.ResponseSPage;
import com.uduemc.biso.node.web.api.service.PageService;
import com.uduemc.biso.node.web.api.service.WebSiteService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/page")
@Api(tags = "页面管理模块")
public class PageController {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private PageService pageServiceImpl;

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private WebSiteService webSiteServiceImpl;

    /**
     * 获取页面的所有数据
     *
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     */
    @PostMapping("/infos")
    @ApiOperation(value = "所有页面", notes = "获取当前语言版本内的所有页面数据信息")
    public JsonResult infos() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        List<SPage> infos = pageServiceImpl.getInfosByHostSiteId();
        if (CollectionUtils.isEmpty(infos)) {
            logger.info("当前站点的s_page为空！");
            return JsonResult.ok();
        }
        ResponseSPage responseSPage = new ResponseSPage(infos);
        return JsonResult.ok(responseSPage);
    }

    /**
     * 通过参数 pageId 以及 requestHolder 获取 sPage 数据
     *
     * @param pageId
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     */
    @PostMapping("/info")
    @ApiOperation(value = "单个页面", notes = "通过传递过来的参数，获取页面的数据信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "pageId", value = "页面ID", required = true, dataType = "long", paramType = "query", defaultValue = "")})
    public JsonResult info(@RequestParam("pageId") long pageId) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        SPage sPage = pageServiceImpl.getCurrentInfoById(pageId);
        if (sPage == null) {
            return JsonResult.illegal();
        }
        return JsonResult.ok(sPage);
    }

    /**
     * 通过id修改name、target、url数据参数
     *
     * @param id
     * @param name
     * @param target
     * @param url
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     */
//	@PostMapping("/updata")
//	public JsonResult updata(@RequestParam("id") long id, @RequestParam("name") String name, @RequestParam("target") String target,
//			@RequestParam("url") String url) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
//		if (StringUtils.isEmpty(name)) {
//			return JsonResult.illegal();
//		}
//		SPage sPage = pageServiceImpl.getCurrentInfoById(id);
//		if (sPage == null) {
//			return JsonResult.illegal();
//		}
//		sPage.setName(name).setTarget(target).setUrl(url);
//		SPage update = pageServiceImpl.updateSPageById(sPage);
//		if (update == null) {
//			return JsonResult.illegal();
//		}
//		webSiteServiceImpl.cacheCurrentSiteClear();
//		return JsonResult.ok(update);
//	}

    /**
     * 新建、更新页面均通过此方法
     *
     * @param requestSPage
     * @param errors
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     * @throws HostSetuptException
     */
    @PostMapping("/save")
    @ApiOperation(value = "后台区域保存页面数据", notes = "适用于新增页面，修改页面的数据保存")
    public JsonResult save(@Valid @RequestBody RequestSPage requestSPage, BindingResult errors)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, HostSetuptException {
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                String field = fieldError.getField();
                logger.info("field: " + field + "defaultMessage: " + defaultMessage);
                return JsonResult.messageError(defaultMessage);
            }
        }
        return pageServiceImpl.save(requestSPage);
    }

    /**
     * 设计区域更新页面
     *
     * @param requestSPage
     * @param errors
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     * @throws HostSetuptException
     */
    @PostMapping("/design-save")
    @ApiOperation(value = "设计区域保存页面数据", notes = "适用于新增页面，修改页面的数据保存")
    public JsonResult designSave(@Valid @RequestBody RequestSPage requestSPage, BindingResult errors)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, HostSetuptException {
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                String field = fieldError.getField();
                logger.info("field: " + field + "defaultMessage: " + defaultMessage);
                return JsonResult.messageError(defaultMessage);
            }
        }
        return pageServiceImpl.save(requestSPage);
    }

    /**
     * 修改页面的排序
     *
     * @param listSPage
     * @param pageId    被点击的那个页面的ID
     * @param errors
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     */
    @PostMapping("/update-order/{pageId:\\d+}")
    public JsonResult updateOrder(@Valid @RequestBody List<SPage> listSPage, @PathVariable("pageId") long pageId, BindingResult errors)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                String field = fieldError.getField();
                logger.info("field: " + field + "defaultMessage: " + defaultMessage);
                return JsonResult.messageError(defaultMessage);
            }
        }
        if (CollectionUtils.isEmpty(listSPage)) {
            return JsonResult.illegal();
        }
        int i = 0;
        for (SPage sPage : listSPage) {
            if (sPage.getHostId().longValue() != requestHolder.getHost().getId().longValue()) {
                return JsonResult.illegal();
            }
            if (i == 0 && sPage.getSiteId().longValue() == 0L) {
                i++;
                continue;
            }
            if (sPage.getSiteId().longValue() != requestHolder.getCurrentSite().getId().longValue()) {
                return JsonResult.illegal();
            }
        }
        List<SPage> updateSPageById = pageServiceImpl.updateSPageById(listSPage);
        if (updateSPageById.size() == listSPage.size()) {
            webSiteServiceImpl.cacheCurrentSiteClear();
            return JsonResult.messageSuccess("操作成功");
        }
        return JsonResult.assistance();
    }

    @PostMapping("/save/list")
    public JsonResult save(@Valid @RequestBody List<SPage> listSPage, BindingResult errors)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                String field = fieldError.getField();
                logger.info("field: " + field + "defaultMessage: " + defaultMessage);
                return JsonResult.messageError(defaultMessage);
            }
        }
        if (CollectionUtils.isEmpty(listSPage)) {
            return JsonResult.illegal();
        }
        int i = 0;
        for (SPage sPage : listSPage) {
            if (sPage.getHostId().longValue() != requestHolder.getHost().getId().longValue()) {
                return JsonResult.illegal();
            }
            if (i == 0 && sPage.getSiteId().longValue() == 0L) {
                i++;
                continue;
            }
            if (sPage.getSiteId().longValue() != requestHolder.getCurrentSite().getId().longValue()) {
                return JsonResult.illegal();
            }
        }
        List<SPage> updateSPageById = pageServiceImpl.updateSPageById(listSPage);
        if (updateSPageById.size() == listSPage.size()) {
            webSiteServiceImpl.cacheCurrentSiteClear();
            return JsonResult.messageSuccess("操作成功");
        }
        return JsonResult.assistance();
    }

    @PostMapping("/valid/rewrite")
    public JsonResult saveRewrite(@Valid @RequestBody RequestSPageRewrite requestSPageRewrite, BindingResult errors)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                String field = fieldError.getField();
                logger.info("field: " + field + "defaultMessage: " + defaultMessage);
                Map<String, Object> error = new HashMap<>();
                error.put("error", defaultMessage);
                return JsonResult.messageError(defaultMessage, error);
            }
        }

        if (!pageServiceImpl.validRewrite(requestSPageRewrite.getId(), requestSPageRewrite.getRewrite())) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "自定义链接系统中已存在");
            return JsonResult.messageError("自定义链接系统中已存在", error);
        }

        return JsonResult.ok(requestSPageRewrite);
    }

    /**
     * 修改页面的显示状态，导航中不显示，同时前台页面无法访问
     *
     * @param id
     * @param status
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     */
    @ApiOperation(value = "修改页面显示状态", notes = "导航中不显示，同时前台页面无法访问该页面")
    @PostMapping("/change-status")
    public JsonResult changeStatus(@RequestParam long id, @RequestParam short status)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        if (id < 1 || status > (short) 1 || status < (short) 0) {
            return JsonResult.illegal();
        }

        boolean changeStatusById = pageServiceImpl.changeStatusById(id, status);
        if (changeStatusById) {
            webSiteServiceImpl.cacheCurrentSiteClear();
            return JsonResult.messageSuccess(1);
        } else {
            return JsonResult.assistance();
        }
    }

    /**
     * 修改页面的隐藏状态，导航中不显示，但是不影响前台页面访问
     *
     * @param id
     * @param hide
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws JsonProcessingException
     * @throws IOException
     */
    @ApiOperation(value = "修改页面隐藏状态", notes = "导航中不显示，但是不影响前台页面访问")
    @PostMapping("/change-hide")
    public JsonResult changeHide(@RequestParam long id, @RequestParam short hide)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        if (id < 1 || hide > (short) 1 || hide < (short) 0) {
            return JsonResult.illegal();
        }

        boolean changeHideById = pageServiceImpl.changeHideById(id, hide);
        if (changeHideById) {
            webSiteServiceImpl.cacheCurrentSiteClear();
            return JsonResult.messageSuccess(1);
        } else {
            return JsonResult.assistance();
        }
    }

    @PostMapping("/bootpage")
    public JsonResult bootpage() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        SPage bootPage = pageServiceImpl.getBootPage();
        return JsonResult.ok(bootPage);
    }

    @PostMapping("/bootpage-save")
    public JsonResult bootpageSave(@RequestParam("status") short status, @RequestParam("guideConfig") String guideConfig)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        SPage bootPage = pageServiceImpl.getBootPage();
        bootPage.setStatus(status);
        bootPage.setGuideConfig(guideConfig);
        SPage updateSPageById = pageServiceImpl.updateSPageById(bootPage);
        return JsonResult.messageSuccess(updateSPageById);
    }

    @PostMapping("/delete")
    public JsonResult delete(@RequestParam("id") long id) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        SPage sPage = pageServiceImpl.getCurrentInfoById(id);
        if (sPage == null) {
            SPage infoById = pageServiceImpl.getInfoById(id);
            if (infoById == null) {
                return JsonResult.messageSuccess("删除成功");
            }
            return JsonResult.illegal();
        }
        if (pageServiceImpl.hasChildren(sPage.getId())) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "删除失败，请先删除子级");
            return JsonResult.messageError("删除失败，请先删除子级", error);
        }
        boolean deleteById = pageServiceImpl.delete(sPage);
        if (!deleteById) {
            return JsonResult.assistance();
        }
        webSiteServiceImpl.cacheCurrentSiteClear();
        return JsonResult.messageSuccess("删除成功", sPage);
    }

    /**
     * 通过系统类型获取页面挂载的系统列表数据
     *
     * @param typeos
     * @return
     * @throws IOException
     * @throws JsonProcessingException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @PostMapping("/infos-with-system-by-types")
    public JsonResult infosWithPageByTypes(@RequestBody List<Long> typeos)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        List<PageSystem> data = pageServiceImpl.getCurrentInfosWithPageByTypes(typeos);
        return JsonResult.ok(data);
    }

    /**
     * 添加该站点的首页
     *
     * @return
     * @throws IOException
     * @throws JsonProcessingException
     * @throws JsonMappingException
     * @throws JsonParseException
     * @throws HostSetuptException
     */
    @PostMapping("/get-home-page-if-not-create")
    public JsonResult getHomePageIfNotCreate() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, HostSetuptException {
        SPage sPage = pageServiceImpl.getCurrentHomePageIfNotCreate();
        webSiteServiceImpl.cacheCurrentSiteClear();
        return JsonResult.ok(sPage);
    }

    /**
     * 页面复制
     *
     * @param sPageCopy
     * @return
     * @throws IOException
     */
    @PostMapping("/copy")
    public JsonResult copy(@Valid @RequestBody RequestSPageCopy sPageCopy) throws IOException {
        return pageServiceImpl.copy(sPageCopy);
    }

}
